package it.unical.canonaco.rende.igpe.game.cbv.guilayer.gamemanagermenu.playdialog;


import it.unical.canonaco.rende.igpe.game.cbv.guilayer.components.OverallGUILayoutFactory;
import it.unical.canonaco.rende.igpe.game.cbv.guilayer.components.SyncHandlerMOLM;
import it.unical.canonaco.rende.igpe.game.cbv.guilayer.components.ThinScrollBar;
import it.unical.canonaco.rende.igpe.game.cbv.guilayer.match.MatchPanel;
import it.unical.canonaco.rende.igpe.game.cbv.guilayer.sprites.SpriteSheetCache;
import it.unical.canonaco.rende.igpe.game.cbv.guilayer.sprites.SpriteSheetInterface;
import it.unical.canonaco.rende.igpe.game.cbv.guilayer.sprites.key.AbstractSheetKey;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.GameManager;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.MatchManager;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.MatchOnLineManager;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.pawn.Character;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.player.BattlePlayer;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.world.Map;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.netgame.MainConnectionServer;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.netgame.BoomerangProtocol;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.netgame.OnLineEnemyController;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.netgame.ServerCondition;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import javax.imageio.ImageIO;
import javax.imageio.stream.FileImageInputStream;
import javax.swing.DefaultListModel;
import javax.swing.DefaultListSelectionModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;

/** */
public class OnLinePPM extends JPanel implements Runnable
{
	/** */
	static public final String NAME = "onlineppm";
	
	/** */
	private BoomerangProtocol connection;
	/** */
	private String key;
	
	/** */
	private Thread connectionThread;
	
	/** */
	private PrePlayMatchDialog dialog;

	/** */
	private JButton fightButton;

	private JButton backButton;
	
	/** */
	private BattlePlayer enemy;
	
	private ServerCondition enemyCondition;
	
	/** */
	private JLabel status;
	
	private SyncHandlerMOLM sync;
	/**
	 * @throws IOException 
	 * @throws UnknownHostException  */
	public OnLinePPM(final PrePlayMatchDialog dialog) 
	{
		super(true);
//		miniIcons = new SpriteSheetCache("cbvapps"+File.separator+"uiresource"+File.separator+"data", new HashMap<AbstractSheetKey, SpriteSheetInterface>());
//		miniIcons.add(sheetKey, sheet);
		enemyCondition = new ServerCondition();
		sync = new SyncHandlerMOLM();
		
		OverallGUILayoutFactory gui = OverallGUILayoutFactory.getInstance();
		
		this.dialog = dialog;
		key = BoomerangProtocol.NO_KEY;
		
		setLayout(new GridBagLayout());
		GridBagConstraints constr = new GridBagConstraints();
		
		constr.gridx = 0;
		constr.gridy = 0;
		constr.anchor = GridBagConstraints.CENTER;
		connection = new BoomerangProtocol("127.0.0.1", MainConnectionServer.WELCOME_PORT);
		
		JPanel panel = new JPanel();
		final MultipleCheckBox mcjcb = new MultipleCheckBox(MatchManager.MINIMUM_CHARACTERS_PER_PLAYER, MatchManager.MAX_CHARACTERS_PER_PLAYER, dialog.getFrameOwner().getGameManager().getClientBattlePlayer());

		DefaultListModel<JListCharacterData> model = new DefaultListModel<>();
		final JList<JListCharacterData> datas = new JList<>();
		
		JListCharacterRender jlcr = new JListCharacterRender();
		datas.setCellRenderer(jlcr);
		datas.setModel(model);
		
//		try {
		for (Character character : dialog.getFrameOwner().getGameManager().getClientPlayer().getCharacters()) 
		{
			JListCharacterData jlcd;
			jlcd = new JListCharacterData(character, new ImageIcon("cbvapps"+File.separator+"uiresource"+File.separator+"data"+File.separator+"roles"+File.separator+"micros"+File.separator+character.getStats().getName()+".png"), mcjcb);
			model.addElement(jlcd);
		}
//		} catch ( IOException e1) {
//			// TODO Auto-generated catch block
//			e1.printStackTrace();
//		}
		panel.add(datas);
//		datas.setSelectionMode(ListSelectionModel.);
		datas.addListSelectionListener(mcjcb);
		datas.setMaximumSize(new Dimension(dialog.getDialog().getWidth()/2,dialog.getDialog().getHeight()));
		datas.setLayoutOrientation(JList.VERTICAL);
//		datas.setVisibleRowCount(-1);
//		panel.setOpaque(false);
		JScrollPane charactersPane = new JScrollPane(datas);
		charactersPane.setVerticalScrollBar(new ThinScrollBar(JScrollBar.VERTICAL));
//		JScrollPane charactersPane = new 
		charactersPane.setMaximumSize(new Dimension(dialog.getDialog().getWidth()/2,dialog.getDialog().getHeight()));
		charactersPane.setMinimumSize(new Dimension(dialog.getDialog().getWidth()/2,dialog.getDialog().getHeight()));
//		charactersPane.add(panel);
		add(charactersPane, constr);
		
		backButton = gui.createButtonUniState(52.0f, "Indietro", 80, 60, OverallGUILayoutFactory.BUTTON_STATE_ACTIVE);
		backButton.addActionListener(new ActionListener() 
		{
			@Override
			public void actionPerformed(ActionEvent e) 
			{
				dialog.show();
			}
		});
		
		constr.gridy = 0;
		constr.gridx = 1;
		JPanel anotherPanel = new JPanel();
		anotherPanel.add(backButton);
		fightButton = gui.createButtonUniState(52.0f, "Combatti", 80, 60, OverallGUILayoutFactory.BUTTON_STATE_ACTIVE);
		anotherPanel.add(fightButton);
		fightButton.setEnabled(false);
		status = new JLabel("Ricerca avversario");
		status.setFont(gui.getParagraphFont().deriveFont(8.0f));
		fightButton.addActionListener(new ActionListener() 
		{
			
			@Override
			public void actionPerformed(ActionEvent arg0) 
			{
				if(mcjcb.isOkState())
				{
					fightButton.setEnabled(false);
					GameManager gameManager = dialog.getFrameOwner().getGameManager();
					connection.sendPlayerInformations(gameManager.getClientBattlePlayer());
					System.out.println("MANDATO INFORMAZIONI DI "+gameManager.getClientBattlePlayer().getNickname());
					
					try 
					{
						while(enemy == null)
						{
							System.out.println("Ninna avversario non caricato, aspetta!");
							enemyCondition.doWait();
						} 
					}catch (InterruptedException e) 
					{
						e.printStackTrace();
					}
					System.out.println("!!ATTESA FINITA GIOCHI CONTRO: "+enemy.getNickname());
					OnLineEnemyController oEnemy = new OnLineEnemyController(dialog.getFrameOwner().getGameManager().getStatsFactory(), dialog.getFrameOwner().getGameManager().getClientBattlePlayer());
					oEnemy.setAiPlayer(enemy);
					
					MatchOnLineManager molm = new MatchOnLineManager(dialog.getFrameOwner().getGameManager().getMatchManager(), oEnemy);
					try {
						sync.settingUp(molm,oEnemy,dialog.getFrameOwner().getGameManager().getClientPlayer(),dialog.getFrameOwner().getGameManager().getClientBattlePlayer(), connection);
						dialog.getFrameOwner().switchTo(new MatchPanel(110, sync.getMap(), molm, dialog.getFrameOwner()));
						dialog.hide();
						molm.startMatch(-1);
						oEnemy.setMatchIsRunning(true);
					} catch (UnknownHostException e) 
					{
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		});
		add(anotherPanel, constr);
		
		constr.gridy = 1;
		constr.gridx = 0;
//		constr.fill = GridBagConstraints.
		add(status, constr);
		connectionThread = new Thread(this);
	}

@Override
public void removeNotify() 
{
	if(key != BoomerangProtocol.NO_KEY)
	{
		try 
		{
			connection.sendState_sh(BoomerangProtocol.REMOVE_ME, key);
			connection.end();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	super.removeNotify();
}

@Override
public void run() 
{	
	try 
	{
		key = connection.sendState(BoomerangProtocol.ADD_ME, BoomerangProtocol.NO_KEY);
		System.out.println("aggiunto come "+key);
		System.out.println("pre map check");
		Map map = connection.mapCheck(dialog.getFrameOwner().getGameManager().getMapManager());
		sync.setMap(map);
		sync.setMapOff(false);
		System.out.println("post map check");
		connection.receiveEnemyConnectionInformations();
		final JPanel tPanel = this;
		new Thread("READING ENEMY INFO")
		{
			public void run() 
			{
				System.out.println("ATTESA RICEVIMENTO");
				enemy = connection.receivePlayerInformations(dialog.getFrameOwner().getGameManager().getStatsFactory());
				System.out.println("ATTESA FINITA GIOCHI CONTRO: "+enemy.getNickname());
				enemyCondition.doNotify();
				status.setVisible(false);
				status.setText("Trovato");
				status.setVisible(true);
//				dialog.getDialog().setVisible(false);
//				dialog.getDialog().setVisible(true);
				sync.setEnemyOff(false);
			};
		}.start();
		
		backButton.setEnabled(false);
		fightButton.setEnabled(true);
		
	} catch (IOException e) 
	{
		e.printStackTrace();
	}
}


public Thread getConnectionThread() 
{
	return connectionThread;
}
}